home *** CD-ROM | disk | FTP | other *** search
/ SPACE 1 / SPACE - Library 1 - Volume 1.iso / demos / 221 / ud.src < prev   
Text File  |  1987-12-28  |  7KB  |  281 lines

  1.  
  2. Just when you thought it was safe to turn your monitor rightside-up...
  3.  
  4. Here are the sources and uuencoded binary to a new version of my
  5. silly upside down desk accessory.  This one refreshes the screen at
  6. more than 10 Hz when there is little change between refreshes.
  7.  
  8. It keeps checksums on 32 byte blocks of the screen and reverses the
  9. changed blocks.
  10.  
  11. I promise not to post any more of these.  Honest.
  12.  
  13. What do you mean, pointless?
  14.  
  15. Jan Gray
  16.  
  17.  
  18. ud.c:
  19. ------------------
  20. /*
  21.  * Upside-down DA, v.2 ...a somewhat less disappointing experiment
  22.  *
  23.  * Jan Gray 1986
  24.  *
  25.  * link: accstart,ud,flip,aesbind,osbind
  26.  */
  27.  
  28. #include "gemdefs.h"
  29. #include "osbind.h"
  30.  
  31. #define    NULL        0
  32. #define    SCR_BYTES    32000L
  33. #define    SCR_ALIGN    512L            /* must page align screen */
  34. #define    Supexec(code)    xbios(38, code)
  35.  
  36. typedef unsigned char    Byte;            /* must be unsigned! */
  37.  
  38. long    Chksums[32000/32];
  39. Byte    RevBytes[256];
  40.  
  41. Byte    *RealScreen;                /* real screen address */
  42. Byte    *FlipScreen;                /* flipped screen address */
  43. Byte    *Phys;                    /* passed to setPhysBase() */
  44.  
  45. setPhysBase();
  46.  
  47. main()
  48. {
  49.     extern int    gl_apid;
  50.     char    menuName[20];
  51.     int    menuID;
  52.     int    event;
  53.     int    msg[8];
  54.     int    ret;
  55.  
  56.     appl_init();
  57.  
  58.     buildRevBytes();
  59.     zapChksums();
  60.  
  61.     RealScreen = Physbase();
  62.     FlipScreen = (Byte *)((Malloc(SCR_BYTES + SCR_ALIGN) + (SCR_ALIGN-1))
  63.                 & ~(SCR_ALIGN-1));
  64.  
  65.     menuName[0] = NULL;
  66.     menuID = menu_register(gl_apid,  menuName);
  67.  
  68.     for (;;) {
  69.         /* Wait for accessory open message */
  70.         strcpy(menuName, "  Upside-down");
  71.         do {
  72.             event = evnt_mesag(msg);
  73.         } while (!(msg[0] == AC_OPEN && msg[4] == menuID));
  74.  
  75.         /* Flip screen */
  76.         refreshFlip();
  77.         Phys = FlipScreen;
  78.         Supexec(setPhysBase);
  79.             
  80.         /*
  81.          * Wait for accessory open or close message or 50 ms timeout.
  82.          */
  83.         strcpy(menuName, "  Rightside-up");
  84.         do {
  85.             event = evnt_multi(MU_MESAG | MU_TIMER,
  86.                        0, 0, 0,
  87.                        0, 0, 0, 0, 0,
  88.                        0, 0, 0, 0, 0,
  89.                        msg, 50, 0,
  90.                         &ret, &ret, &ret, &ret, &ret, &ret);
  91.             if (event & MU_TIMER)
  92.                 refreshFlip();    /* 20 to 150 ms */
  93.         } while (!((event & MU_MESAG) &&
  94.                (msg[0] == AC_OPEN && msg[4] == menuID ||
  95.                 msg[0] == AC_CLOSE && msg[3] == menuID)));
  96.  
  97.         /* Restore screen */
  98.         Phys = RealScreen;
  99.         Supexec(setPhysBase);
  100.     }
  101. }
  102.  
  103. buildRevBytes()                /* Build the byte reversal table */
  104. {
  105.     register int    i;
  106.  
  107.     for (i = 0; i < 256; i++)
  108.         RevBytes[i] =    ((i & 1) << 7) | ((i & 2) << 5) |
  109.                 ((i & 4) << 3) | ((i & 8) << 1) |
  110.                 ((i & 0x10) >> 1) | ((i & 0x20) >> 3) |
  111.                 ((i & 0x40) >> 5) | ((i & 0x80) >> 7);
  112. }
  113.  
  114. zapChksums()                /* Initialize the checksums to ff's */
  115. {
  116.     register long    *p;
  117.     register long    ffffffff    = 0xffffffffL;
  118.  
  119.     for (p = Chksums; p < &Chksums[32000/32]; ) {
  120.         *p++ = ffffffff;
  121.         *p++ = ffffffff;
  122.         *p++ = ffffffff;
  123.         *p++ = ffffffff;
  124.     }
  125. }
  126.  
  127. #define    VBASE_HIGH    (Byte *)0xff8201L
  128. #define    VBASE_LOW    (Byte *)0xff8203L
  129. /*
  130.  * setPhysBase -- set the physical screen to Phys.  I don't use Setscreen()
  131.  * because it seems to clear the old logical screen...I don't want the
  132.  * ST to know that anything funny is going on, just to go merrily on its
  133.  * way writing to what it thinks is the physical screen...
  134.  */
  135. setPhysBase()
  136. {
  137.     *VBASE_HIGH = (Byte)((unsigned long)Phys >> 16);
  138.     *VBASE_LOW  = (Byte)((unsigned long)Phys >> 8);
  139. }
  140.  
  141. /* Writing strcpy here saves us from linking with gemlib */
  142. strcpy(dst, src)
  143. register char    *dst;
  144. register char    *src;
  145. {
  146.     while (*dst++ = *src++)
  147.         ;
  148. }
  149. ----------------------
  150. flip.s:
  151. ----------------------
  152. *
  153. * flip.s
  154. *
  155. * Assembler _refreshFlip.
  156. *
  157. * Reverse the real screen onto the flip screen.  Rather than reversing
  158. * every byte every time called (which is slow -- about 120 ms per call),
  159. * we reverse only those bytes which have changed since the last call.
  160. *
  161. * Instead of saving yet another copy of the screen, we keep a longword
  162. * checksum for each block of 32 bytes.  If a new checksum differs, we save
  163. * it away and reverse that 32 byte block.
  164. *
  165. * Since the screen changes little between calls, this is a big win, reducing
  166. * the average time spent here from about 120 to 20 ms per call.
  167. *
  168. *
  169. * Registers used
  170. * a5    - real screen
  171. * a4    - flip screen start
  172. * a3    - flip screen
  173. * a2    - reverse table
  174. * a1    - checksum table
  175. * a0    - constant 32
  176. * d7-d0    - scratch
  177. .globl _RealScreen
  178. .globl _FlipScreen
  179. .globl _RevBytes
  180. .globl _Chksums
  181. .text
  182. .globl _refreshFlip
  183. _refreshFlip:
  184.     link    a6,#0
  185.     movem.l    d0-d7/a0-a5,-(sp)
  186.     move.l    _RealScreen,a5
  187.     move.l    _FlipScreen,a4
  188.     move.l    a4,a3
  189.     add.l    #32000,a3            * a3 = end of FlipScreen
  190.     move.l    #_RevBytes,a2
  191.     move.l    #_Chksums,a1
  192.     move.l    #32,a0
  193. loop:
  194.     movem.l    (a5)+,d0-d7            * fetch 32 bytes
  195.     add.l    d1,d0                * compute new checksum
  196.     add.l    d2,d0
  197.     add.l    d3,d0
  198.     add.l    d4,d0
  199.     add.l    d5,d0
  200.     add.l    d6,d0
  201.     add.l    d7,d0
  202.     cmp.l    (a1)+,d0            * compare against old checksum
  203.     bne    rev                * reverse line if different
  204.     sub.l    a0,a3                * skip 32 bytes on flip screen
  205. loop1:
  206.     cmp.l    a4,a3                * done?
  207.     bcc    loop
  208.     movem.l    (sp)+,d0-d7/a0-a5
  209.     unlk    a6
  210.     rts
  211.  
  212. rev:
  213.     move.l    d0,-4(a1)            * differs; save new checksum
  214.     sub.l    a0,a5                * adjust a5 to front of 32 bytes
  215.     moveq.l    #0,d0                * load upper byte with 0
  216.     move.b    (a5)+,d0            * copy real byte through byte-
  217.     move.b    0(a2,d0.w),-(a3)        *  reversal table to flip screen
  218.     move.b    (a5)+,d0            * likewise for 31 bytes
  219.     move.b    0(a2,d0.w),-(a3)
  220.     move.b    (a5)+,d0
  221.     move.b    0(a2,d0.w),-(a3)
  222.     move.b    (a5)+,d0
  223.     move.b    0(a2,d0.w),-(a3)
  224.     move.b    (a5)+,d0
  225.     move.b    0(a2,d0.w),-(a3)
  226.     move.b    (a5)+,d0
  227.     move.b    0(a2,d0.w),-(a3)
  228.     move.b    (a5)+,d0
  229.     move.b    0(a2,d0.w),-(a3)
  230.     move.b    (a5)+,d0
  231.     move.b    0(a2,d0.w),-(a3)
  232.     move.b    (a5)+,d0
  233.     move.b    0(a2,d0.w),-(a3)
  234.     move.b    (a5)+,d0
  235.     move.b    0(a2,d0.w),-(a3)
  236.     move.b    (a5)+,d0
  237.     move.b    0(a2,d0.w),-(a3)
  238.     move.b    (a5)+,d0
  239.     move.b    0(a2,d0.w),-(a3)
  240.     move.b    (a5)+,d0
  241.     move.b    0(a2,d0.w),-(a3)
  242.     move.b    (a5)+,d0
  243.     move.b    0(a2,d0.w),-(a3)
  244.     move.b    (a5)+,d0
  245.     move.b    0(a2,d0.w),-(a3)
  246.     move.b    (a5)+,d0
  247.     move.b    0(a2,d0.w),-(a3)
  248.     move.b    (a5)+,d0
  249.     move.b    0(a2,d0.w),-(a3)
  250.     move.b    (a5)+,d0
  251.     move.b    0(a2,d0.w),-(a3)
  252.     move.b    (a5)+,d0
  253.     move.b    0(a2,d0.w),-(a3)
  254.     move.b    (a5)+,d0
  255.     move.b    0(a2,d0.w),-(a3)
  256.     move.b    (a5)+,d0
  257.     move.b    0(a2,d0.w),-(a3)
  258.     move.b    (a5)+,d0
  259.     move.b    0(a2,d0.w),-(a3)
  260.     move.b    (a5)+,d0
  261.     move.b    0(a2,d0.w),-(a3)
  262.     move.b    (a5)+,d0
  263.     move.b    0(a2,d0.w),-(a3)
  264.     move.b    (a5)+,d0
  265.     move.b    0(a2,d0.w),-(a3)
  266.     move.b    (a5)+,d0
  267.     move.b    0(a2,d0.w),-(a3)
  268.     move.b    (a5)+,d0
  269.     move.b    0(a2,d0.w),-(a3)
  270.     move.b    (a5)+,d0
  271.     move.b    0(a2,d0.w),-(a3)
  272.     move.b    (a5)+,d0
  273.     move.b    0(a2,d0.w),-(a3)
  274.     move.b    (a5)+,d0
  275.     move.b    0(a2,d0.w),-(a3)
  276.     move.b    (a5)+,d0
  277.     move.b    0(a2,d0.w),-(a3)
  278.     move.b    (a5)+,d0
  279.     move.b    0(a2,d0.w),-(a3)
  280.     bra    loop1                * continue
  281. O.SNG toÀע:/ÇSTPAT.PRG⇩¬♪tOSUNNING.TNY